import gzip
import os
import re
from io import BytesIO

import PySimpleGUI as sg
from conf.__version__ import __version__
import requests
from pathlib import Path

from bs4 import BeautifulSoup
from PIL import Image, ImageDraw
from conf.settings import config, PNG_DIR, ICO_DIR
from comm.common import logger, Response, Status, respond


def show():
    # 定义窗口的布局
    layout = [
        [sg.Text('请输入app名称 或 图标所在详情页URL：', font=('微软雅黑', 12))],
        [sg.InputText(font=('微软雅黑', 12), key='-IN-', size=(30, 20), pad=(10, 10)),
         sg.Submit('确定', font=('微软雅黑', 11), key='-OK-')],
        [sg.Button('图片目录', font=('微软雅黑', 11), key='-OPEN-'),
         sg.Button('转换格式', font=('微软雅黑', 11), key='-CONVERT-', enable_events=True)],
    ]

    # 创建窗口
    window = sg.Window(f'IconMaker v{__version__}', layout)

    def handle_pic():

        user_input = values['-IN-'].replace(' ', '')
        handler = IconHandler(user_input)
        res = handler.crawl_pic()
        if not res.get('status') == Status.SUCCESS.value:
            return res
        else:
            return handler.convert_png_to_ico()

    while True:
        event, values = window.read()
        if event in (None, 'Cancel'):
            break
        elif event == '-OPEN-':
            os.startfile(ICO_DIR)
        elif event == '-OK-':
            window.perform_long_operation(handle_pic, '-DONE-')
            window['-OK-'].update(disabled=True)
        elif event == '-DONE-':
            res = values[event]
            if res['status'] == Status.FAILURE.value:
                sg.popup_error(res['message'])
            if res['status'] == Status.ERROR.value:
                sg.popup_error(res['message'])
            elif res['status'] == Status.SUCCESS.value:
                # os.startfile(ICO_DIR)
                os.startfile(PNG_DIR)  # 临时
                sg.popup_notify(res['message'], title='图标处理完毕！')
            window['-OK-'].update(disabled=False)
        elif event == '-CONVERT-':
            file_path = sg.popup_get_file('请选择需要转换的PNG文件：', font=('微软雅黑', 11))

            if not file_path:
                continue

            app_name = values['-IN-'].replace(' ', '')
            handler = IconHandler(app_name)

            handler.png_pic_path = Path(file_path).resolve()
            folder = Path(file_path).parent
            handler.ico_pic_path = folder / f'{Path(file_path).stem}.ico'
            res = handler.convert_png_to_ico()

            # os.startfile(handler.ico_pic_path.parent)
            os.startfile(handler.png_pic_path.parent)  # 临时
            sg.popup_notify(res['message'], title='图标格式转换完毕！')

    # 关闭窗口
    window.close()


class IconHandler:

    def __init__(self, user_input: str = None):

        self.png_pic_path = PNG_DIR / f'app.png'
        self.ico_pic_path = ICO_DIR / f'app.ico'
        self.app_market = None

        if user_input:

            if user_input.startswith('https://'):

                logger.info(f'通过APP详情页URL获取图标')
                self.detail_url = user_input

                if user_input.startswith('https://play.google.com'):
                    self.app_market = 'google'
                elif user_input.startswith('https://apps.apple.com'):
                    self.app_market = 'apple'
                elif user_input.startswith('https://apkpure.com') or user_input.startswith('https://image.winudf.com'):
                    self.app_market = 'apkpure'
                elif user_input.startswith('https://img.utdstc.com'):
                    self.app_market = 'uptodown'
                else:
                    logger.info(f'不支持的APP市场：{user_input}')
                logger.info(f'准备从{self.app_market}获取图片')

            else:
                logger.info(f'通过APP名称获取图标')
                self.app_name = user_input
                self.app_market = 'google'

                if self.app_name:
                    self.pkg_id = self.get_pkg_id().get('data').get('pkg_id')

                self.detail_url = f'https://play.google.com/store/apps/details?id={self.pkg_id}&hl=en_US'

                self.png_pic_path = PNG_DIR / f'{self.pkg_id}.png'
                self.ico_pic_path = ICO_DIR / f'{self.pkg_id}.ico'

    def get_pkg_id(self):

        try:
            q_url = f'https://play.google.com/store/search?q={self.app_name}&c=apps'
            resp = requests.get(url=self.detail_url or q_url)
            resp.raise_for_status()

            soup = BeautifulSoup(resp.text, 'html.parser')
            result = soup.select_one('.ipRz4 > a')
            href = result.get('href')
            pkg_id = href.split('id=')[1].split('&')[0]

            logger.info('{}的pkg_id是: {}', self.app_name, pkg_id)
            return respond(Response(data={'pkg_id': pkg_id}))

        except Exception as e:
            logger.info('未查到{}的pkg_id！原因：{}', self.app_name, str(e))
            return respond(Response(status=Status.FAILURE,
                                    message=f'未查到{self.app_name}的pkg_id！'))

    def parse_pic_src_4_play_store(self):
        img_url = ''

        if self.app_market == 'apkpure':
            img_url = re.sub(r'(w=\d+)', f'w={512}', self.detail_url)
            return img_url
        if self.app_market == 'uptodown':
            img_url = self.detail_url.replace(':100', ':512')
            return img_url

        # 需要解析网页
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',  # 正确的User-Agent
            'Accept-Language': 'en-US,en;q=0.9'
        }
        resp = requests.get(url=self.detail_url, headers=headers)
        resp.raise_for_status()

        soup = BeautifulSoup(resp.content, 'html.parser')

        # 获取图标文件URL
        if self.app_market == 'google':
            img = soup.select_one('img.T75of')
            img_url = img.get('src').split('=')[0] + '=w512-h512-rw'
        elif self.app_market == 'apple':
            source_tag = soup.find('source')  # 查找第一个source标签
            if source_tag:
                srcset_value = source_tag.get('srcset')
                img_url = srcset_value.split(',')[0].split(' ')[0]
                img_url = re.sub(r'(\d+x0w)', f'{512}x0w', img_url)

            else:
                print("未找到<source>标签")
            # img = soup.select('picture#ember3 source:nth-child(1)')
            # logger.info(img)
            # img_url = img.get('srcset').split(',')[0].split(' ')[0]
            # img_url = re.sub(r'(\d+x0w)', f'w={512}', img_url)


        else:
            logger.info('不支持的APP市场：{}', self.app_market)
        logger.info(img_url)
        return img_url

    def crawl_pic(self):
        """
        下载PNG图标
        :return:
        """

        logger.info('准备下载图标')
        try:
            pic_src_url = self.parse_pic_src_4_play_store()

            # 获取图片内容
            img_resp = requests.get(url=pic_src_url)
            img_resp.raise_for_status()

            # 使用Pillow打开图像
            image = Image.open(BytesIO(img_resp.content))

            # 确保图片是RGBA模式（包含透明度信息）
            if image.mode != 'RGBA':
                image = image.convert('RGBA')

            # 转换为RGB模式并设置白色背景
            new_image = Image.new("RGB", image.size, "WHITE")
            new_image.paste(image, (0, 0), image)

            # 保存图片
            with open(self.png_pic_path, 'wb') as f:
                new_image.save(f, format='PNG')

            logger.info('PNG格式图标下载完毕！')
            logger.info('PNG图标已保存至：{}', self.png_pic_path)
            return respond(Response(message="PNG格式图标下载完毕"))
        except Exception as e:
            logger.error(e)
            return respond(Response(status=Status.ERROR, message=str(e)))

    @staticmethod
    def add_round_corners(image, radius):
        """
        给图片添加圆角
        :param image: 图片
        :param radius: 半径
        :return:
        """

        # 确保图片是RGBA模式（包含透明度信息）
        if image.mode != 'RGBA':
            image = image.convert('RGBA')

        # 转换为RGB模式并设置白色背景
        new_image = Image.new("RGB", image.size, "WHITE")
        new_image.paste(image, (0, 0), image)
        w, h = new_image.size

        # 备用方案
        # alpha = Image.new('L', (w, h), 0)
        # draw_mask = ImageDraw.Draw(alpha)
        # draw_mask.rounded_rectangle([(0, 0), (w, h)], radius=radius, fill=255)

        # 主要方案
        circle = Image.new('L', (radius * 2, radius * 2), 0)
        draw = ImageDraw.Draw(circle)
        draw.ellipse((0, 0, radius * 2, radius * 2), fill=255)
        alpha = Image.new('L', new_image.size, 255)
        alpha.paste(circle.crop((0, 0, radius, radius)), (0, 0))
        alpha.paste(circle.crop((0, radius, radius, radius * 2)), (0, h - radius))
        alpha.paste(circle.crop((radius, 0, radius * 2, radius)), (w - radius, 0))
        alpha.paste(circle.crop((radius, radius, radius * 2, radius * 2)), (w - radius, h - radius))

        new_image.putalpha(alpha)
        logger.info('圆角处理完毕！')

        return new_image

    def convert_png_to_ico(self, corner_radius_ratio=0.2):
        """
        将PNG图片转ICO
        :param corner_radius_ratio: 圆角比率，数值在0~1之间
        :return:
        """
        if not self.png_pic_path.exists():
            logger.warning('图标文件不存在，无法转换格式！')
            return respond(Response(status=Status.FAILURE, message='图标文件不存在'))

        with Image.open(self.png_pic_path) as im:

            corner_radius = int(min(im.size) * corner_radius_ratio)
            im = self.add_round_corners(im, corner_radius)
            im.save(f'{self.png_pic_path}', format='PNG')

            x, y = config['settings']['ico_size']
            im.save(self.ico_pic_path, format='ICO', sizes=[(x, y)])
            logger.info('图片转ICO操作完毕！')

            msg = f'{x}*{y}的ICO图标已保存至：{self.ico_pic_path}'

            return respond(Response(status=Status.SUCCESS,
                                    message=msg,
                                    data={"ico_path": str(self.ico_pic_path)}))


if __name__ == '__main__':
    show()